<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="yl1uE" id="yl1uE"><span data-lake-id="ub437b285" id="ub437b285">典型回答</span></h1>
  <p data-lake-id="uee524ae5" id="uee524ae5"><span data-lake-id="uc610ceba" id="uc610ceba">假如，我们要用Math.abs对一个Integer取绝对值的时候，如果用如下方式：</span></p>
  <p data-lake-id="uca8c36a7" id="uca8c36a7"><span data-lake-id="u32e12868" id="u32e12868">​</span><br></p>
  <pre lang="java"><code>
Math.abs(orderId.hashCode());	
</code></pre>
  <p data-lake-id="u42e63ba8" id="u42e63ba8"><span data-lake-id="ufcb8708b" id="ufcb8708b">​</span><br></p>
  <p data-lake-id="u7a189a22" id="u7a189a22"><span data-lake-id="u6e339d69" id="u6e339d69"> 得到的结果可能是个负数。原因要从Integer的取值范围说起，int的取值范围是-2^31 —— (2^31) - 1，即-2147483648 至 2147483647</span></p>
  <p data-lake-id="u07380d75" id="u07380d75"><span data-lake-id="uba1a2af2" id="uba1a2af2">​</span><br></p>
  <p data-lake-id="ubfde45fe" id="ubfde45fe"><span data-lake-id="uc86e2855" id="uc86e2855">那么，当我们使用abs取绝对值时候，想要取得-2147483648的绝对值，那应该是2147483648。但是，2147483648大于了2147483647，即超过了int的取值范围。这时候就会发生越界。</span></p>
  <p data-lake-id="uf9f37951" id="uf9f37951"><span data-lake-id="uc89a2c7a" id="uc89a2c7a">​</span><br></p>
  <p data-lake-id="u5068d513" id="u5068d513"><span data-lake-id="ucbdb8d64" id="ucbdb8d64">2147483647用二进制的补码表示是：</span><code data-lake-id="u0c1f9cb5" id="u0c1f9cb5"><span data-lake-id="uc5ba15d8" id="uc5ba15d8">01111111 11111111 11111111 11111111</span></code></p>
  <p data-lake-id="u65238427" id="u65238427"><span data-lake-id="u1bf85a48" id="u1bf85a48">​</span><br></p>
  <p data-lake-id="ue5977110" id="ue5977110"><span data-lake-id="u92a5493f" id="u92a5493f">这个数 +1 得到：</span><code data-lake-id="u027733a9" id="u027733a9"><span data-lake-id="udc5e50ef" id="udc5e50ef">10000000 00000000 00000000 00000000</span></code></p>
  <p data-lake-id="u458446a1" id="u458446a1"><span data-lake-id="ufa095433" id="ufa095433">​</span><br></p>
  <p data-lake-id="u0b558526" id="u0b558526"><span data-lake-id="u4a25e336" id="u4a25e336">这个二进制就是-2147483648的补码。</span></p>
  <p data-lake-id="u77b27402" id="u77b27402"><span data-lake-id="ua1ddbb99" id="ua1ddbb99">​</span><br></p>
  <p data-lake-id="u9a67c0e7" id="u9a67c0e7"><span data-lake-id="u77ea07eb" id="u77ea07eb">虽然，这种情况发生的概率很低，</span><strong><span data-lake-id="u596349e3" id="u596349e3">只有当要取绝对值的数字是-2147483648的时候，得到的数字还是个负数。</span></strong><span data-lake-id="uee31025e" id="uee31025e">​</span></p>
  <p data-lake-id="u73897da7" id="u73897da7"><span data-lake-id="u5ffc1c77" id="u5ffc1c77">​</span><br></p>
  <p data-lake-id="ua356bcf7" id="ua356bcf7"><span data-lake-id="u5acd19b7" id="u5acd19b7">那么，如何解决这个问题呢？</span></p>
  <p data-lake-id="u3056133c" id="u3056133c"><span data-lake-id="u3a5f25c1" id="u3a5f25c1">​</span><br></p>
  <p data-lake-id="ueea096e5" id="ueea096e5"><span data-lake-id="u9f68d11c" id="u9f68d11c">既然是因为越界了导致最终结果变成负数，那就解决越界的问题就行了，那就是在取绝对值之前，把这个int类型转成long类型，这样就不会出现越界了。</span></p>
  <p data-lake-id="ua842f990" id="ua842f990"><span data-lake-id="uac9dab1f" id="uac9dab1f">​</span><br></p>
  <p data-lake-id="ue79c766d" id="ue79c766d"><span data-lake-id="u0a5b364e" id="u0a5b364e">如，前面我们取值逻辑修改为</span></p>
  <p data-lake-id="u1506b9c7" id="u1506b9c7"><span data-lake-id="uda77dcf6" id="uda77dcf6">​</span><br></p>
  <pre lang="java"><code>
Math.abs((long)orderId.hashCode()); 
</code></pre>
  <p data-lake-id="u97373299" id="u97373299"><span data-lake-id="u4edecc05" id="u4edecc05">​</span><br></p>
  <p data-lake-id="u96060fec" id="u96060fec"><span data-lake-id="ued981aad" id="ued981aad">就万无一失了。</span></p>
  <p data-lake-id="u7ae31f29" id="u7ae31f29"><span data-lake-id="uaabfb280" id="uaabfb280">​</span><br></p>
  <p data-lake-id="ue49be8a9" id="ue49be8a9"><span data-lake-id="u36e25587" id="u36e25587">大家可以执行下以下代码：</span></p>
  <p data-lake-id="ud45ef733" id="ud45ef733"><br></p>
  <pre lang="java"><code>
public static void main(String[] args) {
    System.out.println(Math.abs((long)Integer.MIN_VALUE));
}
</code></pre>
  <p data-lake-id="u56346da1" id="u56346da1"><span data-lake-id="ue3a25d95" id="ue3a25d95">​</span><br></p>
  <p data-lake-id="u1f43673f" id="u1f43673f"><span data-lake-id="u33f03bb0" id="u33f03bb0">得到的结果就是：</span></p>
  <p data-lake-id="u28fdc1ef" id="u28fdc1ef"><span data-lake-id="u59ec92ad" id="u59ec92ad">​</span><br></p>
  <p data-lake-id="ub9128a42" id="ub9128a42"><span data-lake-id="ubb28833a" id="ubb28833a"> 2147483648</span></p>
  <p data-lake-id="u2093bbf8" id="u2093bbf8"><span data-lake-id="ua00ac679" id="ua00ac679"> </span></p>
  <p data-lake-id="u52b2270f" id="u52b2270f"><span data-lake-id="u753e5706" id="u753e5706">​</span><br></p>
  <h1 data-lake-id="WXhCt" id="WXhCt"><span data-lake-id="u8f24ee58" id="u8f24ee58">扩展知识</span></h1>
  <p data-lake-id="u90a224c3" id="u90a224c3"><br></p>
  <h2 data-lake-id="cvK2K" id="cvK2K"><span data-lake-id="u9cdf1b12" id="u9cdf1b12">整型的取值范围</span></h2>
  <p data-lake-id="ueac23149" id="ueac23149"><br></p>
  <p data-lake-id="uaf7ea18d" id="uaf7ea18d"><span data-lake-id="u08d84f90" id="u08d84f90">Java中的整型主要包含byte、short、int和long这四种，表示的数字范围也是从小到大的，之所以表示范围不同主要和他们存储数据时所占的字节数有关。</span></p>
  <p data-lake-id="u0fd8c1f0" id="u0fd8c1f0"><span data-lake-id="u9f7ef6e4" id="u9f7ef6e4">​</span><br></p>
  <p data-lake-id="ud963ba33" id="ud963ba33"><span data-lake-id="u86886099" id="u86886099">先来个简单的科普，1字节=8位（bit）。java中的整型属于有符号数。</span></p>
  <p data-lake-id="u2c12d9cb" id="u2c12d9cb"><span data-lake-id="u37cc3b17" id="u37cc3b17">​</span><br></p>
  <p data-lake-id="u6bb9d18b" id="u6bb9d18b"><span data-lake-id="ubed149f1" id="ubed149f1">先来看计算中8bit可以表示的数字：</span></p>
  <p data-lake-id="udf8ff8c4" id="udf8ff8c4"><span data-lake-id="ud4421e8f" id="ud4421e8f">最小值：10000000 （-128）(-2^7) 最大值：01111111（127）(2^7-1)</span></p>
  <p data-lake-id="uc9ee1512" id="uc9ee1512"><span data-lake-id="u79501420" id="u79501420">​</span><br></p>
  <p data-lake-id="u0c131b1f" id="u0c131b1f"><span data-lake-id="u6a16c8e1" id="u6a16c8e1">整型的这几个类型中，</span></p>
  <p data-lake-id="ua99d641d" id="ua99d641d"><span data-lake-id="u4d89552e" id="u4d89552e">​</span><br></p>
  <ul list="u5f3e5bd1">
   <li fid="u22053a95" data-lake-id="u5822a31d" id="u5822a31d"><span data-lake-id="u88b1e8f5" id="u88b1e8f5">byte：byte用1个字节来存储，范围为-128(-2^7)到127(2^7-1)，在变量初始化的时候，byte类型的默认值为0。</span></li>
   <li fid="u22053a95" data-lake-id="u3d230951" id="u3d230951"><span data-lake-id="u93cb1029" id="u93cb1029">short：short用2个字节存储，范围为-32,768 (-2^15)到32,767 (2^15-1)，在变量初始化的时候，short类型的默认值为0，一般情况下，因为Java本身转型的原因，可以直接写为0。</span></li>
   <li fid="u22053a95" data-lake-id="udc58324c" id="udc58324c"><span data-lake-id="u4f15c375" id="u4f15c375">int：int用4个字节存储，范围为-2,147,483,648 (-2^31)到2,147,483,647 (2^31-1)，在变量初始化的时候，int类型的默认值为0。</span></li>
   <li fid="u22053a95" data-lake-id="ub2bf51da" id="ub2bf51da"><span data-lake-id="u5f95699e" id="u5f95699e">long：long用8个字节存储，范围为-9,223,372,036,854,775,808 (-2^63)到9,223,372,036, 854,775,807 (2^63-1)，在变量初始化的时候，long类型的默认值为0L或0l，也可直接写为0。</span></li>
  </ul>
  <p data-lake-id="u1f995b55" id="u1f995b55"><br></p>
  <h3 data-lake-id="sQybc" id="sQybc" style="text-align: justify"><span data-lake-id="ub294effd" id="ub294effd" style="color: rgb(85, 85, 85)">超出范围怎么办</span></h3>
  <p data-lake-id="ub88fb6a9" id="ub88fb6a9" style="text-align: justify"><span data-lake-id="ufa3c40b3" id="ufa3c40b3" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">上面说过了，整型中，每个类型都有一定的表示范围，但是，在程序中有些计算会导致超出表示范围，即溢出。如以下代码：</span></p>
  <p data-lake-id="ud1313cc7" id="ud1313cc7"><span data-lake-id="ubd592307" id="ubd592307"> int i = Integer.MAX_VALUE; int j = Integer.MAX_VALUE; int k = i + j; System.out.println("i (" + i + ") + j (" + j + ") = k (" + k + ")");</span></p>
  <p data-lake-id="u825a7721" id="u825a7721"><span data-lake-id="u20880b29" id="u20880b29">​</span><br></p>
  <p data-lake-id="u72f73cd7" id="u72f73cd7" style="text-align: justify"><span data-lake-id="u9d719d24" id="u9d719d24" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">输出结果：i (2147483647) + j (2147483647) = k (-2)</span></p>
  <p data-lake-id="u9aa94f0c" id="u9aa94f0c" style="text-align: justify"><span data-lake-id="u38d170c9" id="u38d170c9" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">​</span><br></p>
  <p data-lake-id="u81622ef6" id="u81622ef6" style="text-align: justify"><strong><span data-lake-id="u50930ef9" id="u50930ef9" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">这就是发生了溢出，溢出的时候并不会抛异常，也没有任何提示。</span></strong><span data-lake-id="ueeb17b68" id="ueeb17b68" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">所以，在程序中，使用同类型的数据进行运算的时候，</span><strong><span data-lake-id="u1a06045c" id="u1a06045c" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">一定要注意数据溢出的问题。</span></strong></p>
 </body>
</html>